//
// Map.cs
//
// Copyright (C) 2008 Lukas Lipka <lukaslipka@gmail.com>
//

using System;
using System.Collections.Generic;

using Gtk;

using Dashboard.Util;

namespace Dashboard.Mint.Widgets {

	public class Map : EventBox {

		private List<MapPoint> points = new List<MapPoint> ();

		private Gdk.Pixbuf map = null;
		private Gdk.Pixbuf point = null;

		private string icons_dir = null;

		public Map (int w, int h)
		{
			this.icons_dir = System.IO.Path.Combine (PathFinder.Installation, "icons");

			this.point = Rsvg.Pixbuf.FromFileAtSize (System.IO.Path.Combine (icons_dir, "point.svg"), 4, 4);
			this.map = Rsvg.Pixbuf.FromFileAtSize ( System.IO.Path.Combine (icons_dir, "map.svg"), w, h);
		}

		public void AddPoint (string name, double lat, double lon)
		{
			MapPoint point = new MapPoint ();
			point.Name = name;
			point.Latitude = lat;
			point.Longitude = lon;
			
			points.Add (point);
		}

		private void LatLongToXY (double lat, double lon, double width, double height, out int x, out int y)
		{
			x = (int)(((lon / 360) * width) + (width / 2));
			y = (int)(((-lat / 180) * height) + (height / 2));
		}

		private void XYToLatLong (int x, int y, double width, double height, out double lat, out double lon)
		{
			lat = ((-y + (height / 2)) / height) * 180;
			lon = ((x - (width / 2)) / width) * 360;
		}

		protected override bool OnExposeEvent (Gdk.EventExpose evnt)
		{
			if (!IsDrawable)
				return true;

			Cairo.Context gr = Gdk.CairoHelper.Create (evnt.Window);

			gr.Rectangle (Allocation.X, Allocation.Y, Allocation.Width, Allocation.Height);
			Gdk.CairoHelper.SetSourcePixbuf (gr, map, Allocation.X, Allocation.Y);
			gr.Fill ();

			foreach (MapPoint p in points) {
				int x = 0, y = 0;
				LatLongToXY (p.Latitude, p.Longitude, Allocation.Width, Allocation.Height, out x, out y);
				gr.Rectangle (Allocation.X + x - 2, Allocation.Y + y - 2, 4, 4);
				Gdk.CairoHelper.SetSourcePixbuf (gr, point, Allocation.X + x - 2, Allocation.Y + y - 2);
				gr.Fill ();
			}

			CairoFu.DisposeContext (gr);
			
			return true;
		}

		protected override void OnSizeRequested (ref Requisition requisition)
		{
			requisition.Width = Math.Max (map.Width, 160);
			requisition.Height = Math.Max (map.Height, 80);
		}

		private class MapPoint {
			public string Name;
			public double Latitude;
			public double Longitude;
		}
	}
}
